package com.amap.search.service;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.otter.canal.protocol.CanalEntry;
import com.amap.search.entity.db2022.AddressCode;
import com.amap.search.entity.db2022.FileRecord;
import com.amap.search.entity.db2022.PoiRecord;
import com.amap.search.entity.es.PoiRecordEs;
import com.amap.search.entity.vo.PoiRequest;
import com.amap.search.mapper.db2022.AddressCodeMapper;
import com.amap.search.mapper.db2022.FileRecordMapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 从一种数据类型转为另一种数据类型得Service
 */
@Service
@Slf4j
public class TransformService {

    @Resource
    private FileRecordMapper fileRecordMapper;

    @Resource
    private AddressCodeMapper addressCodeMapper;

    private final String EMPTY_STRING = "[]";

    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    public PoiRecordEs getEsPoiFromCanal(CanalEntry.RowData rowData){
        PoiRecordEs record = new PoiRecordEs();
        for (CanalEntry.Column column : rowData.getAfterColumnsList()) {
            switch (column.getName()) {
                case "id":
                    record.setId(Long.parseLong(column.getValue()));
                    break;
                case "poi_id":
                    record.setPoiId(column.getValue());
                    break;
                case "name":
                    record.setName(column.getValue());
                    break;
                case "type":
                    record.setType(column.getValue());
                    break;
                case "type_code":
                    record.setTypeCode(column.getValue());
                    break;
                case "address_code":
                    if (StringUtils.isNotBlank(column.getValue()) && !EMPTY_STRING.equals(column.getValue())) {
                        AddressCode addressCode = addressCodeMapper.queryAddressByCode(column.getValue());
                        if (addressCode == null) {
                            log.error("[es]区域表有漏 ： " + column.getValue());
                            break;
                        } else {
                            record.setAddressCode(column.getValue());
                            record.setAdName(addressCode.getAdName());
                            record.setProvinceName(addressCode.getProvinceName());
                            record.setCityName(addressCode.getCityName());
                        }
                    }
                    break;
                case "address":
                    record.setAddress(column.getValue());
                    break;
                case "tag":
                    record.setTag(column.getValue());
                    break;
                case "location":
                    if (column.getValue().length() > 5) {
                        String[] location = column.getValue().split(",");
                        if (location.length == 2) {
                            record.setLongitude(Double.parseDouble(location[0]));
                            record.setLatitude(Double.parseDouble(location[1]));
                        } else {
                            log.info("经纬度坐标有误：" + column.getValue());
                        }
                    }
                    break;
                case "tel":
                    record.setTel(column.getValue());
                    break;
                case "record_date":
                case "update_date":
                    if(StringUtils.isBlank(column.getValue())){
                        break;
                    }
                    try {
                        Date date = dateFormat.parse(column.getValue());
                        if ("record_date".equals(column.getName())) {
                            record.setRecordDate(date);
                        } else {
                            record.setUpdateDate(date);
                        }
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                    break;
                case "rating":
                case "cost":
                    if (!EMPTY_STRING.equals(column.getValue()) && StringUtils.isNotBlank(column.getValue())) {
                        if ("rating".equals(column.getName())) {
                            record.setRating(new BigDecimal(column.getValue()));
                        } else {
                            record.setCost(new BigDecimal(column.getValue()));
                        }
                    }
                    break;
                case "photos":
                    if (StringUtils.isNotBlank(column.getValue()) && !EMPTY_STRING.equals(column.getValue())) {
                        String[] ids = column.getValue().split(",");
                        EntityWrapper<FileRecord> wrapper = new EntityWrapper<>();
                        wrapper.in("id", ids);
                        List<FileRecord> fileRecords = fileRecordMapper.selectList(wrapper);
                        String photos = fileRecords.stream().map(FileRecord::getFilePath).collect(Collectors.joining(","));
                        record.setPhotos(photos);
                    }
                    break;
            }
        }
        return record;
    }

    public List<PoiRecordEs> getEsPoiFromMysql(List<PoiRecord> poiRecordList){
        if(CollectionUtils.isEmpty(poiRecordList)){
            return null;
        }
        List<PoiRecordEs> poiRecordEsList = new ArrayList<>();
        for(PoiRecord mysqlRecord : poiRecordList){
            PoiRecordEs poiRecordEs = new PoiRecordEs();
            BeanUtil.copyProperties(mysqlRecord, poiRecordEs);
            // 经纬度
            if(mysqlRecord.getLocation().length() > 5){
                String[] location = mysqlRecord.getLocation().split(",");
                if (location.length == 2) {
                    poiRecordEs.setLongitude(Double.parseDouble(location[0]));
                    poiRecordEs.setLatitude(Double.parseDouble(location[1]));
                } else {
                    log.info("经纬度坐标有误：" + mysqlRecord.getLocation());
                }
            }

            // 照片
            if (StringUtils.isNotBlank(mysqlRecord.getPhotos()) && !EMPTY_STRING.equals(mysqlRecord.getPhotos())) {
                String[] ids = mysqlRecord.getPhotos().split(",");
                Wrapper<FileRecord> wrapper = new EntityWrapper<>();
                wrapper.in("id", ids);
                List<FileRecord> fileRecords = fileRecordMapper.selectList(wrapper);
                String photos = fileRecords.stream().map(FileRecord::getFilePath).collect(Collectors.joining(","));
                mysqlRecord.setPhotos(photos);
            }

            // 地名
            if (StringUtils.isNotBlank(mysqlRecord.getAddressCode()) && !EMPTY_STRING.equals(mysqlRecord.getAddressCode())) {
                AddressCode addressCode = addressCodeMapper.queryAddressByCode(mysqlRecord.getAddressCode());
                poiRecordEs.setAddressCode(addressCode.getAdCode());
                poiRecordEs.setAdName(addressCode.getAdName());
                poiRecordEs.setProvinceName(addressCode.getProvinceName());
                poiRecordEs.setCityName(addressCode.getCityName());
            }

            poiRecordEsList.add(poiRecordEs);
        }
        return poiRecordEsList;
    }
}
